package com.foreveross.crawl.adapter.sub.impl20140402.v3.xiechen;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.methods.HttpPost;
import org.drools.lang.DRLParser.throw_key_return;

import com.foreveross.crawl.adapter.PlaneInfoEntityBuilder;
import com.foreveross.crawl.adapter.sub.impl20140402.v3.XieChenAdapter;
import com.foreveross.crawl.common.util.RegHtmlUtil;
import com.foreveross.crawl.domain.airfreight.CabinEntity;
import com.foreveross.crawl.domain.airfreight.TransitEntity;
import com.foreveross.crawl.domain.airfreight.doub.CabinRelationEntity;
import com.foreveross.crawl.domain.airfreight.doub.DoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnCabinEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnDoublePlaneInfoEntity;
import com.foreveross.crawl.domain.airfreight.doub.ReturnTransitEntity;
import com.foreveross.taskservice.common.bean.TaskModel;

/**
 * 携程国际往返程
 * 
 * @author xiangsf 2014-07-18
 *
 */
public class XieChenInterRoundTrip {
	protected Log logger = LogFactory.getLog(getClass());
	
	private final static String DATA_AJAX_REQUEST_URL = "http://flights.ctrip.com/international/AjaxRequest/UI2_0/SearchResultHandler.ashx";

	private TaskModel taskQueue;

	private XieChenAdapter adapter;

	private String conditions = null;
	private String refUrl = null;
	private List<DoublePlaneInfoEntity> roundTrips = null;
	public XieChenInterRoundTrip(XieChenAdapter adapter, TaskModel taskQueue) {
		this.adapter = adapter;
		this.taskQueue = taskQueue;
		roundTrips = new ArrayList<DoublePlaneInfoEntity>();
	}
	private void fetchEnterPage() throws Exception{
		StringBuffer url = new StringBuffer("http://flights.ctrip.com/international/round-");
		Map<String, String> params = new HashMap<String, String>();
		HttpPost post = null;
		String html = null;
		try{		
			url.append(taskQueue.getFromCity().toLowerCase()).append("-").append(taskQueue.getToCity().toLowerCase()).append("-")
			.append(taskQueue.getFromCity().toLowerCase()).append("-").append(taskQueue.getToCity().toLowerCase());
				params.put("txtEndCityCode2", "");	
				params.put("txtEndCityCode1", "");	
				params.put("txtEndAddress2", "");
				params.put("txtEndAddress1", "");
				params.put("txtDatePeriod2", "");
				params.put("txtDatePeriod1", "");
				params.put("txtBeginCityCode2", "");
				params.put("txtBeginCityCode1", "");
				params.put("txtBeginAddress2", "");	
				params.put("txtBeginAddress1", "");	
				params.put("txtAirline", "");
				params.put("Quantity", "1");
				params.put("HomeCityID", "2");
				params.put("homecity_name", taskQueue.getFromCityName()+"("+taskQueue.getFromCity()+")");
				params.put("FlightWay", "d");	
				params.put("Eligibility", "");	
				params.put("drpSubClass", "Y");	
				params.put("destcityID", "250");	
				params.put("destcity1_name", taskQueue.getToCityName()+"("+taskQueue.getToCity()+")");	
				params.put("DDatePeriod1", taskQueue.getFlightDate());	
				params.put("childtype", "ADT");	
				params.put("Airline", "All");	
				params.put("ADatePeriod1", taskQueue.getReturnGrabDate());	
			post = adapter.getBasePost(url.toString(), params);
			post.setHeader("Referer",url.toString());
			post.setHeader("Host","flights.ctrip.com");
			post.setHeader("Connection","keep-alive");
			post.setHeader("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
			post.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			html = adapter.excuteRequest(post);
			adapter.appendPageContents(html);
			conditions = RegHtmlUtil.regStr(html, "condition = '(\\{\"FlightWay\":.*\\})';.*if \\(window.simpleLoader\\)");
			refUrl = url.toString();
			logger.info("在第一个请求页得到的动态参数："+conditions);
		}finally{
			 url = null;
			 params = null;
			 post = null;
			 html = null;
		}
	}
	
	private String fetchFirstSearch() throws Exception{
		HttpPost post = null;
		String html = null;
		Map<String, String> params = new HashMap<String, String>();
		try{
			params.put("SearchMode", "Search");
			params.put("condition", conditions);
			params.put("DisplayMode", "RoundTripGroup");
			post = adapter.getBasePost(DATA_AJAX_REQUEST_URL, params);
			post.setHeader("Referer",refUrl);
			post.setHeader("Host","flights.ctrip.com");
			post.setHeader("Connection","keep-alive");
			post.setHeader("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
			post.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			html = adapter.excuteRequest(post);
			adapter.appendPageContents(html);
			return html;
		}finally{
			post = null;
			html = null;
		}
	}
	
	private String fetchSecondSearch(JSONObject json) throws Exception{
		HttpPost post = null;
		String html = null;
		Map<String, String> params = new HashMap<String, String>();
		try{
			params.put("SearchMode", "TokenSearch");
			params.put("condition", conditions);
			params.put("DisplayMode", "RoundTripGroup");
			params.put("SearchIndex", "1");
			String s=json.getJSONArray("PartitionToken").getString(0);
			params.put("SearchToken", s);
			params.put("t", String.valueOf(System.currentTimeMillis()));		
			post = adapter.getBasePost(DATA_AJAX_REQUEST_URL, params);
			post.setHeader("Referer",refUrl);
			post.setHeader("Host","flights.ctrip.com");
			post.setHeader("Connection","keep-alive");
			post.setHeader("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
			post.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			html = adapter.excuteRequest(post);
			adapter.appendPageContents(html);
			return html;
		}finally{
			post = null;
			html = null;
		}
	}
	
	private String fetchThirdSearch(JSONObject json) throws Exception{
		HttpPost post = null;
		String html = null;
		Map<String, String> params = new HashMap<String, String>();
		try{
			params.put("SearchMode", "TokenSearch");
			params.put("condition", conditions);
			params.put("DisplayMode", "RoundTripGroup");
			params.put("SearchIndex", "2");
			params.put("SearchToken", json.getJSONArray("PartitionToken").getString(1));
			params.put("t", String.valueOf(System.currentTimeMillis()));
			post = adapter.getBasePost(DATA_AJAX_REQUEST_URL, params);
			post.setHeader("Referer",refUrl);
			post.setHeader("Host","flights.ctrip.com");
			post.setHeader("Connection","keep-alive");
			post.setHeader("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
			post.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			html = adapter.excuteRequest(post);
			adapter.appendPageContents(html);
			return html;
		}finally{
			post = null;
			html = null;
		}
	}
	
	private void parseJSONData(JSONObject json) throws Exception{
		DoublePlaneInfoEntity dpie = null;
		ReturnDoublePlaneInfoEntity rdpie = null;
		List<TransitEntity> goTransits = null;
		TransitEntity transitEntity = null;
		List<ReturnTransitEntity> backTransits = null;
		ReturnTransitEntity returnTransitEntity = null;
		CabinEntity goCabin = null;
		ReturnCabinEntity backCabin = null;
		JSONObject fi = null;
		JSONObject gofi = null;
		JSONObject backfi = null;
		JSONObject tfi = null;
		JSONObject cabin = null;
		JSONArray flightInfo = null;
		JSONArray fareList = null;
		JSONArray flightDetail = null;
		JSONArray roundTripFlightList = null;
		try{
			roundTripFlightList = json.getJSONArray("RoundTripFlightList");
		}catch(Exception e){
			return;
		}
		logger.info("解析出的航班数量是："+roundTripFlightList.size());
		for(int i = 0 ;i < roundTripFlightList.size(); i++){
			logger.info("解析第("+i+")个");
			try{
				fi = roundTripFlightList.getJSONObject(i);
				//flightInfo［0］代表去程，［1］代表回程
				flightInfo = fi.getJSONArray("FlightInfo");
				gofi = flightInfo.getJSONObject(0);
				
				flightDetail = gofi.getJSONArray("FlightDetail");
				goTransits = new ArrayList<TransitEntity>();
				for(int j = 0; j < flightDetail.size(); j++){//多个航班为中转
					tfi = flightDetail.getJSONObject(j);
					transitEntity = PlaneInfoEntityBuilder.buildTransitEntity(tfi.getString("FlightNo"), 
							null, tfi.getString("AirlineCode"), tfi.getString("AirlineName"), 
							tfi.getString("AirlineName"), tfi.getString("DPort"), tfi.getString("DCityName"), 
							tfi.getString("APort"), tfi.getString("ACityName"), tfi.getString("CraftType"), TransitEntity.class);
					transitEntity.setStartTime(DateUtils.parseDate(tfi.getString("DepartTime"), new String[]{"yyyy-MM-dd HH:mm:ss","yyyy-MM-dd H:mm:ss"}));
					transitEntity.setEndTime(DateUtils.parseDate(tfi.getString("ArrivalTime"), new String[]{"yyyy-MM-dd HH:mm:ss","yyyy-MM-dd H:mm:ss"}));
					if(tfi.containsKey("TransferTime")) transitEntity.setStayTime(XieChenFormatDataUtils.formatStayTime(tfi.getString("TransferTime")));
					goTransits.add(transitEntity);
				}
				dpie = PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, goTransits.get(0).getCarrierKey(), 
						goTransits.get(0).getCarrierName(), goTransits.get(0).getCarrierFullName(), 
						DateFormatUtils.format(goTransits.get(0).getStartTime(), "yyyy-MM-dd HH:mm:ss"), 
						DateFormatUtils.format(goTransits.get(goTransits.size()-1).getEndTime(), "yyyy-MM-dd HH:mm:ss"), 
						goTransits.get(0).getFlightNo(), null, null, null, goTransits.get(0).getFlightType(), DoublePlaneInfoEntity.class);
				dpie.getTransits().addAll(goTransits);
				//return trip
				backfi = flightInfo.getJSONObject(1);
				flightDetail = backfi.getJSONArray("FlightDetail");
				backTransits = new ArrayList<ReturnTransitEntity>();
				for(int j = 0; j < flightDetail.size(); j++){//多个航班为中转
					tfi = flightDetail.getJSONObject(j);
					returnTransitEntity = PlaneInfoEntityBuilder.buildTransitEntity(tfi.getString("FlightNo"), 
							null, tfi.getString("AirlineCode"), tfi.getString("AirlineName"), 
							tfi.getString("AirlineName"), tfi.getString("DPort"), tfi.getString("DCityName"), 
							tfi.getString("APort"), tfi.getString("ACityName"), tfi.getString("CraftType"), ReturnTransitEntity.class);
					returnTransitEntity.setStartTime(DateUtils.parseDate(tfi.getString("DepartTime"), new String[]{"yyyy-MM-dd HH:mm:ss","yyyy-MM-dd H:mm:ss"}));
					returnTransitEntity.setEndTime(DateUtils.parseDate(tfi.getString("ArrivalTime"), new String[]{"yyyy-MM-dd HH:mm:ss","yyyy-MM-dd H:mm:ss"}));
					if(tfi.containsKey("TransferTime"))  returnTransitEntity.setStayTime(XieChenFormatDataUtils.formatStayTime(tfi.getString("TransferTime")));
					backTransits.add(returnTransitEntity);
				}
				rdpie = PlaneInfoEntityBuilder.buildPlaneInfo(taskQueue, backTransits.get(0).getCarrierKey(), 
						backTransits.get(0).getCarrierName(), backTransits.get(0).getCarrierFullName(), 
						DateFormatUtils.format(backTransits.get(0).getStartTime(), "yyyy-MM-dd HH:mm:ss"), 
						DateFormatUtils.format(backTransits.get(backTransits.size()-1).getEndTime(), "yyyy-MM-dd HH:mm:ss"), 
						backTransits.get(0).getFlightNo(), null, null, null, backTransits.get(0).getFlightType(), ReturnDoublePlaneInfoEntity.class);
				rdpie.getReturnTransits().addAll(backTransits);
				dpie.getReturnPlaneInfos().add(rdpie);
				//价格,会有多个舱位的价格
				fareList = fi.getJSONArray("FareList");
				for(int k = 0;k < fareList.size(); k++){
					cabin = fareList.getJSONObject(k);
					//只获得经济舱的数据，这里写死（否则取得的JSON模型与我们的模型对不上，取得的模型打包价下有时是有多个的不同舱位的）
					goCabin = PlaneInfoEntityBuilder.buildCabinInfo("经济舱", null, null, 
							null,null, null, null, cabin.containsKey("TicketLack" ) ? cabin.getString("TicketLack") : null, CabinEntity.class);
					backCabin = PlaneInfoEntityBuilder.buildCabinInfo("经济舱", null, null, 
							null,null, null, null, cabin.containsKey("TicketLack" ) ? cabin.getString("TicketLack") : null, ReturnCabinEntity.class);
					dpie.getCabins().add(goCabin);
					rdpie.getReturnCabins().add(backCabin);
					CabinRelationEntity relation = new CabinRelationEntity();
					relation.setCabinId(goCabin.getId());
					relation.setReturnCabinId(backCabin.getId());
					relation.setFullPrice(cabin.getDouble("Price"));
					relation.setTaxesPrice(cabin.getDouble("Tax"));
					relation.setTotalFullPrice(relation.getFullPrice()+relation.getTaxesPrice());
					dpie.getCabinRelations().add(relation);
				}
				roundTrips.add(dpie);
			}finally{
				 dpie = null;
				 rdpie = null;
				goTransits = null;
				 transitEntity = null;
				backTransits = null;
				 returnTransitEntity = null;
				 goCabin = null;
				 backCabin = null;
				 fi = null;
				 gofi = null;
				 backfi = null;
				 tfi = null;
				 cabin = null;
				 flightInfo = null;
				 fareList = null;
				 flightDetail = null;
			}
		}
	}
	public List<Object> fetchData() throws Exception {
		List<Object> results = new ArrayList<Object>();
		String html = null;
		JSONObject firstJson = null;
		JSONObject j = new JSONObject();
		try {
			logger.info("开始进入第一个页面。。。。");
			this.fetchEnterPage();
			logger.info("第一次（直飞）航班抓取。。。。");
			html = this.fetchFirstSearch();
			System.out.println(html);
			firstJson = JSONObject.fromObject(html);
			logger.info("解析直飞航班。。。。");
			this.parseJSONData(firstJson);
			logger.info("第二次（中转）航班抓取。。。。");
			html = this.fetchSecondSearch(firstJson);
			j = JSONObject.fromObject(html);
			logger.info("解析中转航班。。。。");
			this.parseJSONData(j);
			//暂时不取多段程的
//			logger.info("第三次（多程）航班抓取。。。。");
//			html = this.fetchThirdSearch(firstJson);
			//j = JSONObject.fromObject(html);
			//logger.info("解析多程航班。。。。");
			//this.parseJSONData(j);
			logger.info("获得的航班数量为："+roundTrips.size());
			results.addAll(roundTrips);
		} finally {
			 html = null;
			 firstJson = null;
			 j = null;
		}
		return results;
	}
}
